package com.cgene.game;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;

/**
 * 敵を定義するためのクラス
 **/
class Enemy {

	private MiyagiQuestView view;		//	MiyazakiQuestViewクラス

	private Bitmap img[];				//	画像

	/** ステータス関連 */
	public int maxHp = 0;				//	最大ヒットポイント
	public int hp = 0;					//	ヒットポイント
	public int str = 0;					//	攻撃力
	public int def = 0;					//	防御力
	public int spd = 0;					//	スピード
	public int exp = 0;					//	経験値
	public String name = "";			//	名称

	public int idx = 0;					//	戦闘シーン中の敵グループ内のインデックス値
	public int maxIndex = 0;			//	戦闘シーン中の敵グループ内の最大インデックス値
	public int drawPosX = 0;			//	描写位置ｘ座標
	public int drawPosY = 0;			//	描写位置ｙ座標

	private int imgIndex = 0;			//	アニメーション用インデックス値

	public boolean skip;				//	スキップフラグ

	/**
	 * 敵を定義します。
	 * @param	view		MiyazakiQuestView
	 * @param	info		敵のステータス値が、[,]区切りで保持されたテキスト
	 * @param	idx			戦闘シーン中の敵グループ内のインデックス値
	 * @param	maxIndex	戦闘シーン中の敵グループ内の最大インデックス値
	 **/
	@SuppressWarnings("unchecked")
	public Enemy(MiyagiQuestView view, String info, int idx, int maxIndex) throws Exception {
		this.view = view;
		//	ステータス情報を分割
		String data[] = MyUtil.split(info, ",");
		int k = 0;
		//	リソース情報を分割
		String enemyRes[] = MyUtil.split(data[k++], "+");

		//	reflectionを使って、リソースから、画像を読み込みます。
		Class cls = Class.forName("com.cgene.game.R$drawable");
		img = new Bitmap[enemyRes.length];
		Resources r = view.getResources();
		for (int i = 0; i < img.length; i ++) {
			img[i] = BitmapFactory.decodeResource(r, view.getResouceInt(cls, enemyRes[i]));
		}

		//	各ステータスを初期化
		this.name= data[k++];
		this.maxHp = Integer.parseInt(data[k++]);
		this.hp = this.maxHp;
		this.str = Integer.parseInt(data[k++]);
		this.def = Integer.parseInt(data[k++]);
		this.spd = Integer.parseInt(data[k++]);
		this.exp = Integer.parseInt(data[k++]);

		this.idx = idx;
		this.maxIndex = maxIndex;
		init();
	}

	/**
	 * 敵を定義します。
	 * @param	view		MiyazakiQuestView
	 * @param	res			リソースのint値配列
	 * @param	name		名称
	 * @param	hp			ヒットポイント
	 * @param	str			攻撃力
	 * @param	def			防御力
	 * @param	spd			スピード
	 * @param	exp			経験値
	 * @param	idx			戦闘シーン中の敵グループ内のインデックス値
	 * @param	maxIndex	戦闘シーン中の敵グループ内の最大インデックス値
	 **/
	public Enemy(MiyagiQuestView view, int res[], String name, int hp, int str, int def, int spd, int exp, int idx, int maxIndex) throws Exception {
		this.view = view;
		img = new Bitmap[res.length];
		Resources r = view.getResources();
		for (int i = 0; i < img.length; i ++) {
			img[i] = BitmapFactory.decodeResource(r, res[i]);
		}
		this.name = name;
		this.maxHp = hp;
		this.hp = this.maxHp;
		this.str = str;
		this.def = def;
		this.spd = spd;
		this.exp = exp;

		this.idx = idx;
		this.maxIndex = maxIndex;
		init();
	}

	/**
	 * 基準値から、微調整された値を返す。
	 * @param	value	基準値
	 * @param	rate	1000分率での微調整率
	 * @param	min		下限値
	 * @param	minus	正規分布にさせるかどうかのフラグ。trueの場合は、基準値から、上下する。falseの場合は、基準値から上になる
	 * @return			微調整された値
	 **/
	private int getTweakedValue(int value, int rate, int min, boolean minus) {
		int tweak;
		if (minus) {
			tweak = value * (MyUtil.nextInt(rate)-rate / 2) / 1000;
		} else {
			tweak = value * MyUtil.nextInt(rate) / 1000;
		}
		int k = value + tweak;
		if (k < min) k = min;
		return k;
	}

	/**
	 * 攻撃するattackerから、ダメージを計算させて、返す。
	 * @param attacker	攻撃者
	 * @return			ダメージ
	 */
	public int getAttackDamage(Enemy attacker) {
		//	ダメージを算出します。
		int power1 = attacker.str * 100 / this.def;	//	強さレベル
		int power2 = attacker.str - this.def;		//	攻撃力 - 防御力
		if (power2 < 10) power2 = 10 - MyUtil.nextInt(8);
		return power1*power2/100;
	}

	/**
	 * ダメージをセットします。
	 * @param damage	ダメージ
	 * @return			結果のヒットポイント
	 */
	public int setDamage(int damage) {
		hp = hp - damage;
		if (hp < 0) hp = 0;
		return hp;
	}

	/**
	 * 各パラメータを基準値から、微調整させる処理と、描写位置を初期化します。
	 * @param damage	ダメージ
	 * @return			結果のヒットポイント
	 */
	public void init() {
		//	以下、パラメータの初期化。ランダムに上下させる。
		if (maxIndex > 0) {
			maxHp = getTweakedValue(maxHp, 120, 10, true);
			hp = maxHp;
			str = getTweakedValue(str, 100, 1, true);
			def = getTweakedValue(def, 100, 1, true);
			spd = getTweakedValue(spd, 100, 1, true);
		}

		//	以下、描写位置の初期化
		if (maxIndex <= 0) {
			//	何もしない。
		} else if (maxIndex == 1) {
			drawPosX = view.displayWidth/2 - img[0].getWidth() / 2;
			drawPosY = 100;
		} else {
			int w = (view.displayWidth - view.battleMarginX * 2)/maxIndex;
			drawPosX = w / 2 - img[0].getWidth() / 2 + view.battleMarginX + w * idx;
			drawPosY = 100;
		}
	}

	/**
	 * アニメーション処理を行った結果の画像を返す。
	 * @param	inc		アニメーションを変更するかどうかのフラグ
	 * @return			画像
	 */
	public Bitmap getEnemyImage(boolean inc) {
		if (inc) imgIndex ++;
		if (imgIndex >= img.length) imgIndex = 0;
		return img[imgIndex];
	}

	/**
	 * 描写処理
	 * @param	canvas		描写キャンバスクラス
	 * @param	paint		描写ペイントクラス
	 * @param	inc			アニメーションを変更するかどうかのフラグ
	 * @param	isSelected	現在、選択されているかのフラグ
	 */
	public void drawEnemy(Canvas canvas, Paint paint, boolean inc, boolean isSelected) {
		if (hp <= 0) return;
		canvas.drawBitmap(getEnemyImage(inc), drawPosX, drawPosY, paint);
		if (isSelected) {
			canvas.drawRect(new RectF(drawPosX - 1, drawPosY - 1,
							drawPosX + img[0].getWidth() + 2,
							drawPosY+img[0].getHeight() + 2), paint);
		}
	}
}
